#ifndef TCP_CLIENT_H
#define TCP_CLIENT_H

#include <QtNetwork>

//为了方便并发和单独处理数据所以单独写个类专门处理
#if 1
//小数据量可以不用线程,收发数据本身默认异步的
class TcpClient : public QObject
#else
//线程方便处理密集运算比如解析图片
class TcpClient : public QThread
#endif
{
    Q_OBJECT
public:
    explicit TcpClient(QTcpSocket *socket, QObject *parent = 0);
    explicit TcpClient(QTcpSocket *socket,  qintptr socketDescriptor, QObject *parent = 0);
    QTcpSocket *m_socket;
private:

    QString m_ip;
    int m_port;
    qintptr m_socketDescriptor;

    /**
     * @brief ascii转字节(发数据)
     * @param data
     * @return
     */
    QByteArray asciiStrToByteArray(const QString &data);

    /**
     * @brief 字节转ASCII码（收数据）
     * @param data
     * @return
     */
    QString byteArrayToAsciiStr(const QByteArray &data);

    /**
     * @brief 字符串转16进制（收数据）
     * @param data
     * @return
     */
    QString byteArrayToHexStr(const QByteArray &data);

    /**
     * @brief 16进制字符串转字符串（发数据）
     * @param data
     * @return
     */
    QByteArray hexStrToByteArray(const QString &data);

    /**
     * @brief 16进制字符串转char
     * @param data
     * @return
     */
    char hexStrToChar(char data);

    /**
     * @brief 数字转16进制的字符串
     * @param decimal
     * @return
     */
    QString decimalToStrHex(int decimal);

    /**
     * @brief 16进制字符串转数据
     * @param strHex
     * @return
     */
    int strHexToDecimal(const QString &strHex);

public:
    /**
     * @brief 得到IP
     * @return
     */
    QString getIP() const;
    /**
     * @brief 得到端口号
     * @return
     */
    int getPort()   const;

private slots:
    // /**
    //  * @brief 断开连接
    //  */
    // void disconnected();
    /**
     * @brief 断开连接
     */
    void disconnected();
    /**
     * @brief 读取数据
     */
    void readData();

signals:
    //void clientDisconnected();
    void sendData(const QString &ip, int port, const QString &data);

    void receiveData(const QString &ip, int port, const QString &data);

    void clientDisconnected(qintptr socketDescriptor);

public slots:
    /**
     * @brief 发送数据
     * @param data
     */
    void sendData(const QString &data);
    /**
     * @brief 套接字断开连接
     */
    void abort();

private:
    //已收到的字节数
    qint64 m_totalBytes = 0;//接受数据的总大小
    quint64 m_receivedBytes = 0;//已接受的数据
    QByteArray m_infoBlock;//帧体内容
    QByteArray m_tmpBlock;//临时存储的数据

    QByteArray m_frameHead;//帧头
    QByteArray m_frameContent;//帧体
    QByteArray m_frameTail;//帧位

    QByteArray m_command;//命令
    QByteArray m_Check;//异或校验
    QByteArray m_length;//长度
    QByteArray m_serialNumber;//序列号
};

#endif // TCP_CLIENT_H
